package analiseSintatica.Regras.Declaracoes;

import java.util.LinkedList;

import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.Regra;
import analiseSintatica.estruturadados.NoArvore;
import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import AnaliseLexicaFinal.EstruturaDeDados.Token;
import analiseSintatica.Regras.Expressoes.RegraExpressao;

/**
 *
 * @author Edney
 */
public class RegraAtribuicaoArray extends Regra {

    RegraExpressao expressao = RegraExpressao.getInstance();
    protected static Regra instancia;
    protected String estrutura = "<atribuicao_array> ::=  '=' '{' [ <expressao> {',' <expressao>} ] '}'";
    
    /**
     * Construtor privado necessario ao singleton
     */
    private RegraAtribuicaoArray() {
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraAtribuicaoArray getInstance() {
        if (instancia == null) {
            instancia = new RegraAtribuicaoArray();
        }
        return (RegraAtribuicaoArray) instancia;
    }

    @Override
    public NoArvore analisar(LinkedList<LinkToken> listaTokens)throws ErroSintaticoException {

        ErroSintaticoException erros = new ErroSintaticoException();

        NoArvore naoterminalAtribuicaoArray = new NoArvore("<AtribuicaoArray>", false);

        naoterminalAtribuicaoArray.adicionaFilho(reconheceToken(listaTokens, "=",estrutura));

        try{
            naoterminalAtribuicaoArray.adicionaFilho(reconheceToken(listaTokens, "{",estrutura));

        }
        catch(ErroSintaticoException e){

        }

        if(expressao.getPrimeiro().contains(listaTokens.getFirst().getToken())){

            naoterminalAtribuicaoArray.adicionaFilho(RegraExpressao.getInstance().analisar(listaTokens));

            while(listaTokens.getFirst().getToken().equals("delimitador") && listaTokens.getFirst().getLexema().equals(",")){

                naoterminalAtribuicaoArray.adicionaFilho(reconheceLexema(listaTokens, "delimitador", ",",estrutura));

                try{
                   naoterminalAtribuicaoArray.adicionaFilho(RegraExpressao.getInstance().analisar(listaTokens));

                }
                catch (ErroSintaticoException e){
                    while(e.size() != 0)
                        erros.addErros(e.getErros());

                }

            }

        }

        try{
            naoterminalAtribuicaoArray.adicionaFilho(reconheceToken(listaTokens, "}",estrutura));

        }
        catch(ErroSintaticoException e){

        }

        return naoterminalAtribuicaoArray;
    }

    @Override
    protected void setPrimeiro() {
         primeiro.add("=");
    }

    @Override
    protected void setSeguinte() {
        this.seguinte.add("void");
        this.primeiro.add("typedef");
        this.primeiro.add("const");
        this.primeiro.add("identificador");
        this.primeiro.add("char");
        this.primeiro.add("int");
        this.primeiro.add("float");
        this.primeiro.add("boolean");
        this.seguinte.add(",");
    }
}
